home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / PASCAL / 0921.ZIP / MAZE.ARC / MAZE.PAS
Pascal/Delphi Source File  |  1987-11-22  |  23KB  |  678 lines

  1. PROGRAM maze(INPUT,OUTPUT);
  2.          This program builds a maze on your CRT.  After the maze is built,
  3.     you may use the cursor keys to solve it.  Press "Q" to quit or press
  4.     "S" to have the computer solve the maze.  If the computer solves the 
  5.     maze, you must press some key to exit.  A different random number seed
  6.     will produce a different maze.  Each maze has exactly one solution that
  7.     does not involve backtracking (passing through a doorway more than once).
  8.       
  9.         Written by James L. Dean.
  10.  
  11. }   
  12.  
  13.   CONST
  14.  
  15. {  Columns and rows in maze. } 
  16.  
  17.     max_num_columns=159;
  18.     max_num_rows=99;    
  19.  
  20. {  Color assignments. } 
  21.  
  22.     erase=2;     {  Wall must be positive     } 
  23.     wall=3;      {  Wall, passage, and path   } 
  24.     passage=0;   {  must be different.  Wall, } 
  25.     path=1;      {  path, and erase must be   } 
  26.                  {  different                 } 
  27.  
  28.   TYPE
  29.     regs = RECORD
  30.                  al    : CHAR;
  31.                  ah    : BYTE;
  32.                  bx    : INTEGER;
  33.                  cx    : INTEGER;
  34.                  dx    : INTEGER;
  35.                  bp    : INTEGER;
  36.                  si    : INTEGER;
  37.                  di    : INTEGER;
  38.                  ds    : INTEGER;
  39.                  es    : INTEGER;
  40.                  flags : INTEGER
  41.                END;
  42.   VAR
  43.     delta_x                 : ARRAY [0..3] OF ARRAY [0..23] OF INTEGER;
  44.     delta_y                 : ARRAY [0..3] OF ARRAY [0..23] OF INTEGER;
  45.     magnitude_delta_x       : INTEGER;
  46.     magnitude_delta_y       : INTEGER;
  47.     num_columns             : INTEGER;
  48.     num_rows                : INTEGER;
  49.     register                : REGS;
  50.     r_n                     : ARRAY [0..7] OF INTEGER;
  51.     r_n_index_1             : INTEGER;
  52.     r_n_index_2             : INTEGER;
  53.     screen                  : ARRAY [0..16383] OF BYTE ABSOLUTE $B800:$0000;
  54.     screen_image            : ARRAY [0..16383] OF BYTE;
  55.     tem_int                 : INTEGER;
  56.     twice_magnitude_delta_x : INTEGER;
  57.     twice_magnitude_delta_y : INTEGER;
  58.     x                       : INTEGER;
  59.     x_max                   : INTEGER;
  60.     x_next                  : INTEGER;
  61.     x_out                   : INTEGER;
  62.     y                       : INTEGER;
  63.     y_max                   : INTEGER;
  64.     y_next                  : INTEGER;
  65.     y_out                   : INTEGER;
  66.     y_out_max               : INTEGER;
  67.  
  68.  
  69.   PROCEDURE initialize; 
  70.     VAR
  71.       delta_index_1a : INTEGER;
  72.       delta_index_1b : INTEGER;
  73.       delta_index_1c : INTEGER;
  74.       delta_index_1d : INTEGER;
  75.       delta_index_2  : INTEGER;
  76.       seed           : STRING[8];
  77.       tem_int        : INTEGER;
  78.     BEGIN
  79.       ClrScr;
  80.       WRITELN(OUTPUT,'                                 Maze Generator');
  81.       WRITELN(OUTPUT,' ');
  82.       WRITELN(OUTPUT,' ');
  83.       WRITELN(OUTPUT,' ');
  84.       WRITELN(OUTPUT,
  85. '     This program will generate a maze.  After the maze is generated, you');
  86.       WRITELN(OUTPUT,
  87. 'may use the cursor keys to solve it.  Press Q to quit or S to have the');
  88.       WRITELN(OUTPUT,
  89. 'computer solve the maze.  If the computer solves the maze, you must press');
  90.       WRITELN(OUTPUT,
  91. 'some key to exit.');
  92.       WRITELN(OUTPUT,' ');
  93.       REPEAT
  94.         WRITE(OUTPUT,'     Number of columns? ');
  95.         READLN(INPUT,num_columns);
  96.         IF ((num_columns < 1) OR (num_columns > max_num_columns)) THEN
  97.           BEGIN
  98.             WRITE(OUTPUT,
  99.              '? The number of columns must be between 1 and ');
  100.             WRITE(OUTPUT,max_num_columns);
  101.             WRITELN(OUTPUT,', inclusively')
  102.           END
  103.       UNTIL ((num_columns >= 1) AND (num_columns <= max_num_columns));
  104.       WRITELN(OUTPUT,' ');
  105.       REPEAT
  106.         WRITE(OUTPUT,'     Number of rows? ');
  107.         READLN(INPUT,num_rows);
  108.         IF ((num_rows < 1) OR (num_rows > max_num_rows)) THEN
  109.           BEGIN
  110.             WRITE(OUTPUT,
  111.              '? The number of rows must be between 1 and ');
  112.             WRITE(OUTPUT,max_num_rows);
  113.             WRITELN(OUTPUT,', inclusively')
  114.           END
  115.       UNTIL ((num_rows >= 1) AND (num_rows <= max_num_rows));
  116.       WRITELN(OUTPUT,' ');
  117.       WRITE(OUTPUT,'     Random number seed? ');
  118.       READLN(INPUT,seed);
  119.       r_n_index_1:=0;
  120.       FOR r_n_index_2:=1 TO Length(seed) DO
  121.         BEGIN
  122.           tem_int:=ORD(seed[r_n_index_2]);
  123.           WHILE (tem_int >= 29) DO tem_int:=tem_int-29;
  124.           r_n[r_n_index_1]:=tem_int;
  125.           r_n_index_1:=r_n_index_1+1
  126.         END;
  127.       r_n_index_2:=7;
  128.       WHILE (r_n_index_1 > 0) DO
  129.         BEGIN
  130.           r_n_index_1:=r_n_index_1-1;
  131.           r_n[r_n_index_2]:=r_n[r_n_index_1];
  132.           r_n_index_2:=r_n_index_2-1
  133.         END;
  134.       WHILE (r_n_index_2 >= 0) DO
  135.         BEGIN
  136.           r_n[r_n_index_2]:=19;
  137.           r_n_index_2:=r_n_index_2-1
  138.         END;
  139.       magnitude_delta_x:=319 DIV num_columns DIV 2;
  140.       twice_magnitude_delta_x:=magnitude_delta_x+magnitude_delta_x;
  141.       magnitude_delta_y:=199 DIV num_rows DIV 2;
  142.       twice_magnitude_delta_y:=magnitude_delta_y+magnitude_delta_y;
  143.       x_max:=twice_magnitude_delta_x*num_columns;
  144.       y_max:=twice_magnitude_delta_y*num_rows;
  145.       delta_x[0][0]:=-magnitude_delta_x;
  146.       delta_y[1][0]:=magnitude_delta_y;
  147.       delta_x[2][0]:=magnitude_delta_x;
  148.       delta_y[3][0]:=-magnitude_delta_y;
  149.       delta_y[0][0]:=0;
  150.       delta_x[1][0]:=0;
  151.       delta_y[2][0]:=0;
  152.       delta_x[3][0]:=0;
  153.       delta_index_2:=-1;
  154.       FOR delta_index_1a:=0 TO 3 DO
  155.         FOR delta_index_1b:=0 TO 3 DO
  156.           IF delta_index_1a <> delta_index_1b THEN
  157.             FOR delta_index_1c:=0 TO 3 DO
  158.               IF ((delta_index_1a <> delta_index_1c)
  159.               AND (delta_index_1b <> delta_index_1c)) THEN 
  160.                 FOR delta_index_1d:=0 TO 3 DO
  161.                   IF ((delta_index_1a <> delta_index_1d)
  162.                   AND (delta_index_1b <> delta_index_1d)
  163.                   AND (delta_index_1c <> delta_index_1d)) THEN
  164.                     BEGIN
  165.                       delta_index_2:=delta_index_2+1;
  166.                       delta_x[delta_index_1a][delta_index_2]:=delta_x[0][0];
  167.                       delta_y[delta_index_1a][delta_index_2]:=delta_y[0][0];
  168.                       delta_x[delta_index_1b][delta_index_2]:=delta_x[1][0];
  169.                       delta_y[delta_index_1b][delta_index_2]:=delta_y[1][0];
  170.                       delta_x[delta_index_1c][delta_index_2]:=delta_x[2][0];
  171.                       delta_y[delta_index_1c][delta_index_2]:=delta_y[2][0];
  172.                       delta_x[delta_index_1d][delta_index_2]:=delta_x[3][0];
  173.                       delta_y[delta_index_1d][delta_index_2]:=delta_y[3][0]
  174.                     END
  175.     END;
  176.  
  177.   PROCEDURE draw_horizontal(x_1,x_2,y,color : INTEGER);
  178.     VAR
  179.       bank_offset  : INTEGER;
  180.       bank_segment : INTEGER;
  181.       byte_in_line : INTEGER;
  182.       byte_mask    : BYTE;
  183.       color_mask   : BYTE;
  184.       line_in_bank : INTEGER;
  185.       pixel_index  : INTEGER;
  186.       shift_index  : INTEGER;
  187.       x            : INTEGER;
  188.     BEGIN
  189.       line_in_bank:=y SHR 1;
  190.       IF y = line_in_bank+line_in_bank THEN
  191.         bank_segment:=$b800
  192.       ELSE
  193.         bank_segment:=$ba00;
  194.       byte_in_line:=x_1 SHR 2;
  195.       bank_offset:=80*line_in_bank;
  196.       bank_offset:=bank_offset+byte_in_line;
  197.       pixel_index:=x_1-(byte_in_line SHL 2);
  198.       byte_mask:=3;
  199.       color_mask:=color;
  200.       shift_index:=3-pixel_index;
  201.       WHILE (shift_index > 0) DO
  202.         BEGIN
  203.           color_mask:=color_mask SHL 2;
  204.           byte_mask:=byte_mask SHL 2;
  205.           shift_index:=shift_index-1
  206.         END;
  207.       byte_mask:=NOT byte_mask;
  208.       FOR x:=x_1 TO x_2 DO
  209.         BEGIN
  210.           Mem[bank_segment:bank_offset]
  211.            :=(Mem[bank_segment:bank_offset] AND byte_mask) OR color_mask;
  212.           pixel_index:=pixel_index+1;
  213.           IF pixel_index > 3 THEN
  214.             BEGIN
  215.               pixel_index:=0;
  216.               byte_mask:=$3f;
  217.               color_mask:=color;
  218.               color_mask:=color_mask SHL 6;
  219.               bank_offset:=bank_offset+1
  220.             END
  221.           ELSE
  222.             BEGIN
  223.               byte_mask:=NOT byte_mask;
  224.               byte_mask:=byte_mask SHR 2;
  225.               byte_mask:=NOT byte_mask;
  226.               color_mask:=color_mask SHR 2
  227.             END
  228.         END
  229.     END;
  230.  
  231.   PROCEDURE draw_vertical(x,y_1,y_2,color : INTEGER);
  232.     VAR
  233.       bank_1_offset  : INTEGER;
  234.       bank_1_segment : INTEGER;
  235.       bank_2_offset  : INTEGER;
  236.       bank_2_segment : INTEGER;
  237.       byte_in_line   : INTEGER;
  238.       byte_mask      : BYTE;
  239.       color_mask     : BYTE;
  240.       line_in_bank   : INTEGER;
  241.       offset         : INTEGER;
  242.       shift_index    : INTEGER;
  243.       tem_int        : INTEGER;
  244.       y              : INTEGER;
  245.     BEGIN
  246.       line_in_bank:=y_1 SHR 1;
  247.       IF y_1 = line_in_bank+line_in_bank THEN
  248.         BEGIN
  249.           bank_1_segment:=$b800;
  250.           bank_1_offset:=0;
  251.           bank_2_segment:=$ba00;
  252.           bank_2_offset:=0
  253.         END
  254.       ELSE
  255.         BEGIN
  256.           bank_1_segment:=$ba00;
  257.           bank_1_offset:=0;
  258.           bank_2_segment:=$b800;
  259.           bank_2_offset:=80
  260.         END;
  261.       byte_in_line:=x SHR 2;
  262.       offset:=80*line_in_bank;
  263.       offset:=offset+byte_in_line;
  264.       bank_1_offset:=bank_1_offset+offset;
  265.       bank_2_offset:=bank_2_offset+offset;
  266.       byte_mask:=$03;
  267.       color_mask:=color;
  268.       shift_index:=3;
  269.       shift_index:=shift_index-(x-(byte_in_line SHL 2));
  270.       WHILE (shift_index > 0) DO
  271.         BEGIN
  272.           color_mask:=color_mask SHL 2;
  273.           byte_mask:=byte_mask SHL 2;
  274.           shift_index:=shift_index-1
  275.         END;
  276.       byte_mask:=NOT byte_mask;
  277.       FOR y:=y_1 TO y_2 DO
  278.         BEGIN
  279.           Mem[bank_1_segment:bank_1_offset]
  280.            :=(Mem[bank_1_segment:bank_1_offset] AND byte_mask) OR color_mask;
  281.           tem_int:=bank_1_offset;
  282.           bank_1_offset:=bank_2_offset;
  283.           bank_2_offset:=tem_int+80;
  284.           tem_int:=bank_1_segment;
  285.           bank_1_segment:=bank_2_segment;
  286.           bank_2_segment:=tem_int
  287.         END
  288.     END;
  289.  
  290.   FUNCTION color(x,y : INTEGER) : INTEGER;
  291.     VAR
  292.       bank_offset  : INTEGER;
  293.       bank_segment : INTEGER;
  294.       byte_in_line : INTEGER;
  295.       line_in_bank : INTEGER;
  296.       byte_mask    : BYTE;
  297.       shift_index  : INTEGER;
  298.     BEGIN
  299.       line_in_bank:=y SHR 1;
  300.       IF y = line_in_bank+line_in_bank THEN
  301.         bank_segment:=$b800
  302.       ELSE
  303.         bank_segment:=$ba00;
  304.       byte_in_line:=x SHR 2;
  305.       bank_offset:=80*line_in_bank+byte_in_line;
  306.       shift_index:=x-(byte_in_line SHL 2);
  307.       IF shift_index < 2 THEN
  308.         IF shift_index = 0 THEN
  309.           color:=(Mem[bank_segment:bank_offset] AND $c0) SHR 6
  310.         ELSE
  311.           color:=(Mem[bank_segment:bank_offset] AND $30) SHR 4
  312.       ELSE
  313.         IF shift_index = 2 THEN
  314.           color:=(Mem[bank_segment:bank_offset] AND $0c) SHR 2
  315.         ELSE
  316.           color:=Mem[bank_segment:bank_offset] AND $03
  317.     END;
  318.  
  319.   PROCEDURE add_room;
  320.     VAR
  321.       delta_index_1 : BYTE;
  322.       delta_index_2 : BYTE;
  323.     BEGIN
  324.       y_out_max:=y+magnitude_delta_y-1;
  325.       FOR y_out:=y-magnitude_delta_y+1 TO y_out_max DO
  326.         draw_horizontal(x-magnitude_delta_x+1,x+magnitude_delta_x-1,y_out,
  327.          passage);
  328.       delta_index_1:=0;
  329.       REPEAT
  330.         delta_index_2:=r_n[0];
  331.         r_n_index_1:=0;
  332.         FOR r_n_index_2:=1 TO 7 DO
  333.           BEGIN
  334.             tem_int:=r_n[r_n_index_2];
  335.             r_n[r_n_index_1]:=tem_int;
  336.             r_n_index_1:=r_n_index_1+1;
  337.             delta_index_2:=delta_index_2+tem_int;
  338.             IF delta_index_2 >= 29 THEN
  339.               delta_index_2:=delta_index_2-29
  340.           END;
  341.         r_n[7]:=delta_index_2
  342.       UNTIL (delta_index_2 < 24);
  343.       WHILE (delta_index_1 <= 3) DO
  344.         BEGIN
  345.           x_next:=x+2*delta_x[delta_index_1][delta_index_2];
  346.           IF ((x_next <= 0) OR (x_next >= x_max)) THEN
  347.             delta_index_1:=delta_index_1+1
  348.           ELSE
  349.             BEGIN
  350.               y_next:=y+2*delta_y[delta_index_1][delta_index_2];
  351.               IF ((y_next <= 0) OR (y_next >= y_max)) THEN
  352.                 delta_index_1:=delta_index_1+1
  353.               ELSE
  354.                 IF color(x_next,y_next) = path THEN
  355.                   BEGIN
  356.                     IF x = x_next THEN
  357.                       draw_horizontal(x-magnitude_delta_x+1,
  358.                        x+magnitude_delta_x-1,(y+y_next) DIV 2,passage)
  359.                     ELSE
  360.                       draw_vertical((x+x_next) DIV 2,y-magnitude_delta_y+1,
  361.                        y+magnitude_delta_y-1,passage);
  362.                     x:=x_next;
  363.                     y:=y_next;
  364.                     add_room;
  365.                     x:=x-2*delta_x[delta_index_1][delta_index_2];
  366.                     y:=y-2*delta_y[delta_index_1][delta_index_2]
  367.                   END
  368.                 ELSE
  369.                   delta_index_1:=delta_index_1+1
  370.             END
  371.         END
  372.     END;
  373.  
  374.   PROCEDURE generate_maze;
  375.     VAR
  376.       tem_char     : BYTE;
  377.       video_offset : INTEGER;
  378.     BEGIN
  379.       GraphColorMode;
  380.       Palette(0);
  381.       tem_char:=path;
  382.       tem_char:=4*tem_char;
  383.       tem_char:=tem_char+path;
  384.       tem_char:=4*tem_char;
  385.       tem_char:=tem_char+path;
  386.       tem_char:=4*tem_char;
  387.       tem_char:=tem_char+path;
  388.       video_offset:=0;
  389.       FOR y_out:=1 TO 100 DO
  390.         FOR x_out:=1 TO 80 DO
  391.           BEGIN
  392.             Mem[$b800:video_offset]:=tem_char;
  393.             Mem[$ba00:video_offset]:=tem_char;
  394.             video_offset:=video_offset+1
  395.           END;
  396.       FOR y_out:=0 TO 199 DO
  397.         draw_horizontal(x_max+1,319,y_out,0);
  398.       FOR y_out:=y_max+1 TO 199 DO
  399.         draw_horizontal(0,319,y_out,0);
  400.       x_out:=0;
  401.       WHILE (x_out <= x_max) DO
  402.         BEGIN
  403.           draw_vertical(x_out,0,y_max,wall);
  404.           x_out:=x_out+twice_magnitude_delta_x
  405.         END;
  406.       y_out:=0;
  407.       WHILE (y_out <= y_max) DO
  408.         BEGIN
  409.           draw_horizontal(0,x_max,y_out,wall);
  410.           y_out:=y_out+twice_magnitude_delta_y
  411.         END;
  412.       IF ODD(num_columns) THEN
  413.         x:=num_columns*magnitude_delta_x
  414.       ELSE
  415.         x:=(num_columns-1)*magnitude_delta_x;
  416.       IF ODD(num_rows) THEN
  417.         y:=num_rows*magnitude_delta_y
  418.       ELSE
  419.         y:=(num_rows-1)*magnitude_delta_y;
  420.       add_room;
  421.       draw_horizontal(1,twice_magnitude_delta_x-1,0,passage);
  422.       draw_horizontal(x_max-twice_magnitude_delta_x+1,x_max,y_max,passage);
  423.       MOVE(screen,screen_image,16384);
  424.       SOUND(1000);
  425.       DELAY(333);
  426.       NOSOUND
  427.     END;
  428.  
  429.   PROCEDURE let_user_try_to_solve;
  430.     VAR
  431.       delta_index_1 : INTEGER;
  432.       frequency     : INTEGER;
  433.       passage_found : BOOLEAN;
  434.       tem_int       : INTEGER;
  435.     BEGIN
  436.       register.ah:=8;
  437.       x:=magnitude_delta_x;
  438.       y:=magnitude_delta_y;
  439.       y_next:=0;
  440.       draw_vertical(x,0,y,path);
  441.       REPEAT
  442.         REPEAT
  443.           passage_found:=TRUE;
  444.           Intr(33,register);
  445.           IF ((register.al <> 'Q')
  446.           AND (register.al <> 'q')
  447.           AND (register.al <> 'S')
  448.           AND (register.al <> 's')) THEN
  449.             BEGIN
  450.               IF register.al = #0 THEN
  451.                 BEGIN
  452.                   Intr(33,register);
  453.                   CASE register.al OF
  454.                     #72: delta_index_1:=3;
  455.                     #77: delta_index_1:=2;
  456.                     #80: delta_index_1:=1;
  457.                     #75: delta_index_1:=0;
  458.                     ELSE
  459.                       BEGIN
  460.                         passage_found:=FALSE;
  461.                         SOUND(120);
  462.                         DELAY(278);
  463.                         NOSOUND;
  464.                         register.al:=' '
  465.                       END
  466.                    END
  467.                 END
  468.               ELSE
  469.                 BEGIN
  470.                   CASE register.al OF
  471.                     #56: delta_index_1:=3;
  472.                     #54: delta_index_1:=2;
  473.                     #50: delta_index_1:=1;
  474.                     #52: delta_index_1:=0;
  475.                     ELSE
  476.                       BEGIN
  477.                         passage_found:=FALSE;
  478.                         SOUND(120);
  479.                         DELAY(278);
  480.                         NOSOUND
  481.                       END
  482.                     END
  483.                 END;
  484.               IF passage_found THEN
  485.                 BEGIN
  486.                   x_next:=x+delta_x[delta_index_1][0];
  487.                   y_next:=y+delta_y[delta_index_1][0];
  488.                   IF color(x_next,y_next) = wall THEN
  489.                     BEGIN
  490.                       passage_found:=FALSE;
  491.                       SOUND(120);
  492.                       DELAY(278);
  493.                       NOSOUND
  494.                     END
  495.                   ELSE
  496.                     BEGIN
  497.                       IF y_next = 0 THEN
  498.                         BEGIN
  499.                           passage_found:=FALSE;
  500.                           SOUND(120);
  501.                           DELAY(278);
  502.                           NOSOUND
  503.                         END
  504.                     END
  505.                 END
  506.             END
  507.         UNTIL ((passage_found)
  508.         OR     (register.al = 'Q')
  509.         OR     (register.al = 'q')
  510.         OR     (register.al = 'S')
  511.         OR     (register.al = 's'));
  512.         IF ((register.al <> 'Q')
  513.         AND (register.al <> 'q')
  514.         AND (register.al <> 'S')
  515.         AND (register.al <> 's')) THEN
  516.           BEGIN
  517.             x_next:=x_next+delta_x[delta_index_1][0];
  518.             y_next:=y_next+delta_y[delta_index_1][0];
  519.             IF y_next <= y_max THEN
  520.               BEGIN
  521.                 tem_int:=color(x_next,y_next);
  522.                 IF x = x_next THEN
  523.                   IF y < y_next THEN
  524.                     IF tem_int = path THEN
  525.                       draw_vertical(x,y,y_next,erase)
  526.                     ELSE
  527.                       draw_vertical(x,y,y_next,path)
  528.                   ELSE
  529.                     IF tem_int = path THEN
  530.                       draw_vertical(x,y_next,y,erase)
  531.                     ELSE
  532.                       draw_vertical(x,y_next,y,path)
  533.                 ELSE
  534.                   IF x < x_next THEN
  535.                     IF tem_int = path THEN
  536.                       draw_horizontal(x,x_next,y,erase)
  537.                     ELSE
  538.                       draw_horizontal(x,x_next,y,path)
  539.                   ELSE
  540.                     IF tem_int = path THEN
  541.                       draw_horizontal(x_next,x,y,erase)
  542.                     ELSE
  543.                       draw_horizontal(x_next,x,y,path);
  544.                 x:=x_next;
  545.                 y:=y_next
  546.               END
  547.           END
  548.       UNTIL ((y_next > y_max)
  549.       OR     (register.al = 'Q')
  550.       OR     (register.al = 'q')
  551.       OR     (register.al = 'S')
  552.       OR     (register.al = 's'));
  553.       IF y_next > y_max THEN
  554.         BEGIN
  555.           draw_vertical(x,y,y_max,path);
  556.           frequency:=10;
  557.           FOR delta_index_1:=1 TO 100 DO
  558.             BEGIN
  559.               SOUND(frequency);
  560.               DELAY(56);
  561.               NOSOUND;
  562.               frequency:=frequency+10
  563.             END;
  564.           REPEAT
  565.             Intr(33,register);
  566.             IF ((register.al <> 'Q')
  567.             AND (register.al <> 'q')
  568.             AND (register.al <> 'S')
  569.             AND (register.al <> 's')) THEN
  570.               BEGIN
  571.                 SOUND(120);
  572.                 DELAY(278);
  573.                 NOSOUND
  574.               END;
  575.             IF register.al = #0 THEN
  576.               BEGIN
  577.                 Intr(33,register);
  578.                 register.al:=' '
  579.               END
  580.           UNTIL ((register.al = 'Q')
  581.           OR     (register.al = 'q')
  582.           OR     (register.al = 'S')
  583.           OR     (register.al = 's'))
  584.         END
  585.       END;
  586.  
  587.   PROCEDURE try_adjacent_room;
  588.     VAR
  589.       delta_index_1 : BYTE;
  590.     BEGIN
  591.       delta_index_1:=0;
  592.       WHILE ((delta_index_1 <= 3) AND (y_next <= y_max)) DO
  593.         BEGIN
  594.           x_next:=x+delta_x[delta_index_1][0];
  595.           y_next:=y+delta_y[delta_index_1][0];
  596.           IF color(x_next,y_next) = passage THEN
  597.             BEGIN
  598.               x_next:=x_next+delta_x[delta_index_1][0];
  599.               y_next:=y_next+delta_y[delta_index_1][0];
  600.               IF y_next <= y_max THEN
  601.                 BEGIN
  602.                   IF x = x_next THEN
  603.                     IF y < y_next THEN
  604.                       draw_vertical(x,y,y_next,path)
  605.                     ELSE
  606.                       draw_vertical(x,y_next,y,path)
  607.                   ELSE
  608.                     IF x < x_next THEN
  609.                       draw_horizontal(x,x_next,y,path)
  610.                     ELSE
  611.                       draw_horizontal(x_next,x,y,path);
  612.                   x:=x_next;
  613.                   y:=y_next;
  614.                   try_adjacent_room
  615.                 END;
  616.               IF y_next <= y_max THEN
  617.                 BEGIN
  618.                   x_next:=x;
  619.                   y_next:=y;
  620.                   x:=x-2*delta_x[delta_index_1][0];
  621.                   y:=y-2*delta_y[delta_index_1][0];
  622.                   IF x = x_next THEN
  623.                     IF y < y_next THEN
  624.                       draw_vertical(x,y,y_next,passage)
  625.                     ELSE
  626.                       draw_vertical(x,y_next,y,passage)
  627.                   ELSE
  628.                     IF x < x_next THEN
  629.                       draw_horizontal(x,x_next,y,passage)
  630.                     ELSE
  631.                       draw_horizontal(x_next,x,y,passage);
  632.                   delta_index_1:=delta_index_1+1
  633.                 END
  634.             END
  635.           ELSE
  636.             delta_index_1:=delta_index_1+1
  637.         END
  638.     END;
  639.  
  640.   PROCEDURE optionally_have_computer_solve;
  641.     VAR
  642.       tem_int : INTEGER;
  643.     BEGIN
  644.       IF ((register.al = 'S') 
  645.       OR  (register.al = 's')) THEN
  646.         BEGIN
  647.           MOVE(screen_image,screen,16384);
  648.           x:=magnitude_delta_x;
  649.           y:=magnitude_delta_y;
  650.           y_next:=y+magnitude_delta_y;
  651.           draw_vertical(x,0,y,path);
  652.           try_adjacent_room;
  653.           draw_vertical(x,y,y_max,path);
  654.           SOUND(1000);
  655.           DELAY(333);
  656.           NOSOUND;
  657.           register.ah:=8;
  658.           Intr(33,register);
  659.           IF register.al = #0 THEN
  660.             Intr(33,register)
  661.         END
  662.     END;
  663.  
  664.   PROCEDURE terminate;
  665.     BEGIN
  666.       TextMode
  667.     END;
  668.  
  669.   BEGIN
  670.     initialize;
  671.     generate_maze;
  672.     let_user_try_to_solve;
  673.     optionally_have_computer_solve;
  674.     terminate
  675.   END.
  676. 
  677.